package com.shitou.springai1.admin.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.shitou.springai1.admin.entity.dto.FileDto;
import com.shitou.springai1.admin.service.FileService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 文件管理控制器
 */
@RestController
@PreAuthorize("hasRole('ADMIN')")
@RequestMapping("/api/admin/")
@RequiredArgsConstructor
public class FileController {

    private final FileService fileService;
    private static final String FILE_STORAGE_PATH = "src/main/resources/static/files/";

    /**
     * 获取文件列表
     */
    @GetMapping("files")
    public ResponseEntity<?> getFiles(
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "6") int pageSize,
            @RequestParam(required = false) String keyword) {
        try {
            List<Map<String, Object>> files = fileService.getFiles(pageNum, pageSize, keyword);
            // 构建前端需要的分页格式
            Map<String, Object> response = new HashMap<>();
            response.put("total", fileService.count(
                    keyword != null && !keyword.trim().isEmpty() ?
                            new QueryWrapper<FileDto>()
                                    .like("file_name", keyword.trim())
                                    .or()
                                    .like("file_id", keyword.trim()) : null
            ));
            response.put("records", files);
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("服务器处理请求时发生错误：" + e.getMessage());
        }
    }

    /**
     * 上传文件
     */
    @PostMapping("files")
    public ResponseEntity<?> uploadFile(@RequestBody Map<String, String> requestBody) {
        try {
            String fileName = requestBody.get("fileName");
            String fileContent = requestBody.get("fileContent");

            if (fileName == null || fileContent == null || fileName.isEmpty() || fileContent.isEmpty()) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                        .body("文件名和文件内容不能为空");
            }

            // 确保目录存在
            File directory = new File(FILE_STORAGE_PATH);
            if (!directory.exists()) {
                directory.mkdirs();
            }

            // 生成唯一文件名
            String fileId = java.util.UUID.randomUUID().toString();
            int lastDotIndex = fileName.lastIndexOf(".");
            String fileExtension = lastDotIndex > 0 ? fileName.substring(lastDotIndex) : "";
            String newFileName = fileId + fileExtension;
            String filePath = FILE_STORAGE_PATH + newFileName;

            // 保存文件内容
            byte[] fileBytes = Base64.getDecoder().decode(fileContent);
            Files.write(Paths.get(filePath), fileBytes);

            // 保存文件信息到数据库
            FileDto fileDto = FileDto.builder()
                    .fileName(fileName)
                    .fileUrl(filePath)
                    .fileId(fileId)  // 设置file_id作为文件标识
                    .build();

            if (fileService.saveFile(fileDto)) {
                // 处理文件内容并存储到向量数据库
                // 注意：这里需要根据文件类型进行不同的处理，这里简化处理
                String textContent = extractTextFromFile(fileBytes, fileExtension);
                if (textContent != null && !textContent.isEmpty()) {
                    fileService.processAndStoreFileToVectorStore(fileDto, textContent);
                }
                return ResponseEntity.ok("文件上传成功");
            } else {
                // 删除已保存的文件
                Files.deleteIfExists(Paths.get(filePath));
                return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                        .body("文件信息保存失败");
            }
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                    .body("文件数据格式不正确");
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("文件保存失败");
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("服务器处理请求时发生错误：" + e.getMessage());
        }
    }

    /**
     * 删除文件
     */
    @DeleteMapping("files/{fileId}")
    public ResponseEntity<?> deleteFile(@PathVariable String fileId) {
        try {
            if (fileId == null || fileId.isEmpty()) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                        .body("文件标识不能为空");
            }

            // 使用file_id作为删除依据
            FileDto fileDto = fileService.getByFileId(fileId);
            if (fileDto == null) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND)
                        .body("找不到指定的文件");
            }

            // 先删除数据库记录
            if (fileService.deleteFile(fileDto.getId())) {
                // 再删除实际文件
                if (fileDto.getFileUrl() != null && !fileDto.getFileUrl().isEmpty()) {
                    try {
                        Files.deleteIfExists(Paths.get(fileDto.getFileUrl()));
                    } catch (IOException e) {
                        System.err.println("删除文件失败: " + e.getMessage());
                        // 数据库记录已删除，文件删除失败不影响返回结果
                    }
                }
                return ResponseEntity.ok("文件删除成功");
            } else {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                        .body("文件删除失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("服务器处理请求时发生错误：" + e.getMessage());
        }
    }

    /**
     * 下载文件
     */
    @GetMapping("files/{fileId}/download")
    public ResponseEntity<?> downloadFile(@PathVariable String fileId) {
        try {
            FileDto fileDto = fileService.getByFileId(fileId);
            if (fileDto == null || fileDto.getFileUrl() == null || fileDto.getFileUrl().isEmpty()) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND)
                        .body("找不到指定的文件");
            }

            File file = new File(fileDto.getFileUrl());
            if (!file.exists() || !file.isFile()) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND)
                        .body("文件不存在");
            }

            // 读取文件内容
            byte[] fileBytes = Files.readAllBytes(file.toPath());

            // 设置响应头
            String encodedFileName = URLEncoder.encode(fileDto.getFileName(), StandardCharsets.UTF_8.toString())
                    .replace("+", "%");
            org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders();
            headers.add("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName);
            headers.add("Content-Type", "application/octet-stream");

            return new ResponseEntity<>(fileBytes, headers, HttpStatus.OK);
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("文件读取失败");
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("服务器处理请求时发生错误：" + e.getMessage());
        }
    }

    /**
     * 从文件中提取文本内容
     * 支持多种常见文件类型的内容提取
     */
    private String extractTextFromFile(byte[] fileBytes, String fileExtension) {
        try {
            // 对于文本文件，直接转换为字符串
            String extension = fileExtension.toLowerCase();

            if (".txt".equals(extension)) {
                return new String(fileBytes, StandardCharsets.UTF_8);
            }
            // 对于PDF文件，我们可以提取基本信息
            else if (".pdf".equals(extension)) {
                // 实际应用中应该使用PDFBox或iText等库来提取PDF内容
                // 这里简化处理，返回文件名和文件大小信息
                return String.format("PDF文件：%s\n文件大小：%d KB\n可用于问答的内容将在向量数据库中处理。",
                        fileExtension, fileBytes.length / 1024);
            }
            // 对于Word文档
            else if (".doc".equals(extension) || ".docx".equals(extension)) {
                // 实际应用中应该使用Apache POI库来提取Word文档内容
                return String.format("Word文档：%s\n文件大小：%d KB\n文档内容已准备好用于问答系统。",
                        fileExtension, fileBytes.length / 1024);
            }
            // 对于Excel表格
            else if (".xls".equals(extension) || ".xlsx".equals(extension)) {
                // 实际应用中应该使用Apache POI库来提取Excel内容
                return String.format("Excel表格：%s\n文件大小：%d KB\n表格数据已准备好用于数据分析和问答。",
                        fileExtension, fileBytes.length / 1024);
            }
            // 对于PowerPoint演示文稿
            else if (".ppt".equals(extension) || ".pptx".equals(extension)) {
                // 实际应用中应该使用Apache POI库来提取PowerPoint内容
                return String.format("PowerPoint演示文稿：%s\n文件大小：%d KB\n演示内容已准备好用于问答系统。",
                        fileExtension, fileBytes.length / 1024);
            }
            // 对于压缩文件
            else if (".zip".equals(extension) || ".rar".equals(extension) || ".7z".equals(extension)) {
                return String.format("压缩文件：%s\n文件大小：%d KB\n包含多个文件，已存储供系统访问。",
                        fileExtension, fileBytes.length / 1024);
            }
            // 对于图片文件
            else if (".jpg".equals(extension) || ".jpeg".equals(extension) || ".png".equals(extension) || ".gif".equals(extension)) {
                return String.format("图片文件：%s\n文件大小：%d KB\n图片已存储，可通过智能问答系统描述图片内容。",
                        fileExtension, fileBytes.length / 1024);
            }
            // 对于其他类型的文件，返回基本信息
            else {
                return String.format("文件类型：%s\n文件大小：%d KB\n文件内容已存储到向量数据库，可通过问答系统访问。",
                        fileExtension, fileBytes.length / 1024);
            }
        } catch (Exception e) {
            System.err.println("提取文件内容失败: " + e.getMessage());
            return null;
        }
    }
}
